/**
 * @file    main.c 
 * @author  18408107475@163.com
 * @version V1.0.0
 * @date    2025-06-15
 * @brief   主程序文件，实现OLED显示相关功能及一些计数显示
 * @details 
 * 硬件配置：
 *   - MCU: STM32F103ZET6 (72MHz Cortex-M3)
 * 
 * 软件特性：
 *   - 初始化USART1、OLED等硬件
 *   - 进行OLED的多种显示操作（全屏点亮、清屏、显示字符数字、显示汉字、显示位图等）
 *   - 实现一些计数逻辑并在OLED上显示
 */

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"          // STM32标准外设库（包含核心寄存器定义、中断控制器等相关定义）
#include "Delay.h"              // 精确延时函数库（基于SysTick实现，精度±1us）
#include "USART1_Config.h"      // USART1初始化及printf重定向（设置波特率115200）
#include "OLED_SSD1315_Config.h"// OLED SSD1315驱动配置相关头文件，包含OLED操作函数声明等
#include "OLED_BMP.h"          // 包含OLED位图数据的头文件

/* 私有变量定义 --------------------------------------------------------------*/
bool FillScreen(u8 pattern);  // 声明自定义的FillScreen函数，用于填充OLED屏幕部分区域

/**
 * @brief  主程序入口
 * @param  None
 * @retval int 程序状态码（实际不会返回，因为while(1)循环不会退出）
 * @note   系统执行流程：
 *         1. 初始化硬件（USART1、OLED等）
 *         2. 进行一系列OLED显示操作（全屏点亮、清屏、显示汉字、显示位图等）
 *         3. 进入主循环，实现计数逻辑并在OLED上显示
 */
int main(void)
{
    /* 硬件初始化阶段 ------------------------------------------------*/
    USART1_Config(115200);     // 初始化USART1，设置波特率为115200，8位数据位，无校验位，1位停止位
    OLED_SSD1315_Init();        // 初始化OLED SSD1315，配置相关寄存器等使其处于可用状态

    OLED_SSD1315_Display_On(); // 开启OLED显示，使能内部升压电路等让屏幕开始工作

    OLED_SSD1315_ON();         // 将OLED屏幕全屏点亮（写入0xFF数据）
    Delay_ms(100);             // 延时100毫秒，可观察全屏点亮效果
    OLED_SSD1315_Clear();      // 清屏，将OLED显存写入0x00，屏幕显示全黑
    Delay_ms(100);             // 延时100毫秒

    // 以下代码为之前注释掉的显示字符、字符串、数字、汉字等操作示例
    // OLED_SSD1315_ShowChar(0, 0, 'A', 8);
    // OLED_SSD1315_ShowString(0, 1, "Hello World!", 8, 1);
    // OLED_SSD1315_ShowNum(0, 2, 123456789, 9, 8);
    // Delay_s(5);  // 延时5秒，可观察显示效果
    // OLED_SSD1315_Clear();
    // OLED_SSD1315_ShowChinese(0,   0, 0);
    // OLED_SSD1315_ShowChinese(16,  0, 1);
    // OLED_SSD1315_ShowChinese(32,  0, 2);
    // OLED_SSD1315_ShowChinese(48,  0, 3);
    // OLED_SSD1315_ShowChinese(64,  0, 4);
    // OLED_SSD1315_ShowChinese(80,  0, 5);
    // OLED_SSD1315_ShowChinese(96,  0, 6);
    // OLED_SSD1315_ShowChinese(112, 0, 7);
    // OLED_SSD1315_ShowChinese(128, 0, 8);
    // OLED_SSD1315_ShowChinese(0,   2, 9);
    // OLED_SSD1315_ShowChinese(16,  2, 10);
    // Delay_s(5);
    // OLED_SSD1315_Clear();

    OLED_SSD1315_DrawBitmap(0, 0, 128, 64, BMP1); // 在OLED指定区域（0,0到128,64）绘制位图BMP1
    OLED_SSD1315_Set_Pos(30,2);                   // 设置OLED显示位置为列30，页2（页2对应实际的第17 - 24行像素，因为每页8行）
    FillScreen(0x00);                            // 调用自定义函数填充OLED部分区域（页2 - 5，列0 - 99）为0x00（黑色）

    u8 x = 19;    // 定义变量x，可能用于计数（假设是某种计数值）
    u8 y = 41;    // 定义变量y，可能用于计数（假设是某种计数值）
    u8 j = 0;     // 定义变量j，可能用于计数（假设是某种计数值）
    u8 z = 0;     // 定义变量z，可能用于计数（假设是某种计数值）
    u8 k = 16;    // 定义变量k，可能用于计数（假设是某种计数值）

    OLED_SSD1315_ShowString(48,2,":",16,0);      // 在OLED指定位置（列48，页2）显示":"字符，字体大小16，不自动换行
    OLED_SSD1315_ShowString(77,2,":",16,0);      // 在OLED指定位置（列77，页2）显示":"字符，字体大小16，不自动换行

    OLED_SSD1315_ShowNum(25, 5,2025, 4, 16);     // 在OLED指定位置（列25，页5）显示数字2025，显示宽度4位，字体大小16
    OLED_SSD1315_ShowString(57,5,"-",16,0);      // 在OLED指定位置（列57，页5）显示"-"字符，字体大小16，不自动换行
    OLED_SSD1315_ShowNum(65, 5,06, 2, 16);       // 在OLED指定位置（列65，页5）显示数字06，显示宽度2位，字体大小16
    OLED_SSD1315_ShowString(81,5,"-",16,0);      // 在OLED指定位置（列81，页5）显示"-"字符，字体大小16，不自动换行

    /* 主任务循环 ----------------------------------------------------*/
    while (1)
    {
        // OLED_SSD1315_FillScreen(0x55);    // 注释掉的棋盘格填充代码（可取消注释测试）
        if(z++ == 34){                      // z变量递增，当达到32时执行后续操作
            z=0;                            // z变量重置为0
            j++;                            // j变量递增
            if(j==60){                      // j变量达到60时执行后续操作
                j=0;                        // j变量重置为0
                y++;                        // y变量递增
                if(y==60){                  // y变量达到60时执行后续操作
                    y=0;                    // y变量重置为0
                    x++;                    // x变量递增
                    if(x==24){              // x变量达到24时执行后续操作
                        x=0;                // x变量重置为0
                        k++;                // k变量递增
                    }
                }
            }
        }

        OLED_SSD1315_ShowNum(30, 2, x, 2, 16); // 在OLED指定位置（列30，页2）显示x变量值，显示宽度2位，字体大小16
        OLED_SSD1315_ShowNum(60, 2, y, 2, 16); // 在OLED指定位置（列60，页2）显示y变量值，显示宽度2位，字体大小16
        OLED_SSD1315_ShowNum(85, 2, j, 2, 16); // 在OLED指定位置（列85，页2）显示j变量值，显示宽度2位，字体大小16
        OLED_SSD1315_ShowNum(89, 5,k, 2, 16);  // 在OLED指定位置（列89，页5）显示k变量值，显示宽度2位，字体大小16
    }
    
    /* 程序理论上不会执行到此处 */
    return 0;                  // 符合C语言标准要求的返回值（实际不会执行到这里，因为在while(1)循环中）
}

/************************ (C) COPYRIGHT 2025 Embedded Team *****END OF FILE****/

// 自定义函数：填充OLED屏幕部分区域（页2 - 5，列0 - 99）
bool FillScreen(u8 pattern) 
{
    u8 page, col;
    
    for (page = 2; page < 6; page++)  // 遍历页2到页5（共4页）
    {
        /* 设置当前页地址（0xB0~0xB7，每页对应不同的垂直显示区域） */
        if (!OLED_SSD1315_Write_Command(0xB0 | page)) {
            return false;  // 页地址设置失败，返回false
        }
        
        /* 设置列起始地址（0x00设置低4位列地址，0x10设置高4位列地址，组合成完整列地址） */
        if (!OLED_SSD1315_Write_Command(0x00) || 
            !OLED_SSD1315_Write_Command(0x10)) {
            return false;  // 列地址设置失败，返回false
        }
        
        /* 填充当前页的0 - 99列 */
        for (col = 0; col < 100; col++) 
        {
            if (!OLED_SSD1315_Write_Data(pattern)) {
                return false;  // 数据写入失败，返回false
            }
        }
    }
    return true;  // 填充成功，返回true
}
